
package com.hexinfo.dmpro.sparing.service.impl;

import cn.hutool.core.date.BetweenFormater;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hexinfo.dmpro.common.utils.CommonConstants;
import com.hexinfo.dmpro.common.utils.ScanCommonConstants;
import com.hexinfo.dmpro.sparing.dto.TableDistCPDTO;
import com.hexinfo.dmpro.sparing.dto.TotalDTO;
import com.hexinfo.dmpro.sparing.model.HotStandbyLogSource;
import com.hexinfo.dmpro.sparing.model.HotStandbyLogTable;
import com.hexinfo.dmpro.sparing.dao.HotStandbyLogTableMapper;
import com.hexinfo.dmpro.sparing.service.HotStandbyLogTableService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 热备表级日志分析表
 *
 * @author zax
 * @date 2023-11-18 14:33:21
 */
@Service
public class HotStandbyLogTableServiceImpl extends ServiceImpl<HotStandbyLogTableMapper, HotStandbyLogTable> implements HotStandbyLogTableService {

    @Autowired
    private HotStandbyLogTableMapper hotStandbyLogTableMapper;

    @Override
    public Page queryList(Page page, HotStandbyLogTable hotStandbyLogTable) {
        LambdaQueryWrapper<HotStandbyLogTable> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(HotStandbyLogTable::getDel,CommonConstants.STATUS_NORMAL);
        Page returnPage = this.baseMapper.selectPage(page, wrapper);
        return returnPage;
    }

    /**
     * 通过任务id，查出这个任务下 like 这个状态的表
     */
    @Override
    public List<HotStandbyLogTable> queryLikeList(String tableId,String state) {
        LambdaQueryWrapper<HotStandbyLogTable> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(HotStandbyLogTable::getSourceId,tableId);
        wrapper.like(HotStandbyLogTable::getTaskState,state);
        return this.baseMapper.selectList(wrapper);
    }

    /**
     * 按照源id，获取所有表
     */
    @Override
    public List<HotStandbyLogTable> querySourceId(String sourceId) {
        LambdaQueryWrapper<HotStandbyLogTable> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(HotStandbyLogTable::getSourceId,sourceId)
                .eq(HotStandbyLogTable::getDel,CommonConstants.STATUS_NORMAL);
        return this.getBaseMapper().selectList(wrapper);
    }

    /**
     * 按照条件获取数据
     */
    @Override
    public IPage<HotStandbyLogTable> getHotStandbyLogTables(Page page, HotStandbyLogTable hotStandbyLogTable) {
        IPage<HotStandbyLogTable> resultPage = hotStandbyLogTableMapper.getHotStandbyLogTables(page, hotStandbyLogTable);
        return resultPage;
    }

    /**
     * 获取当天全部表的成功、失败、进行中数量
     */
    @Override
    public TotalDTO getStateAllNum() {
        String taskDate = DateUtil.format(DateUtil.date(), "yyyyMMdd");
        TotalDTO resultPage = hotStandbyLogTableMapper.getStateAllNum(taskDate,
                ScanCommonConstants.ClusterName.CG.value,
                ScanCommonConstants.ClusterName.DZX.value,
                ScanCommonConstants.ClusterName.JXZ.value,
                ScanCommonConstants.ClusterName.TBSB.value,
                ScanCommonConstants.ClusterName.SXSB.value,
                ScanCommonConstants.ClusterName.SCSB.value,
                ScanCommonConstants.ClusterName.BDSB.value);
        return resultPage;
    }

    /**
     * 新增表级日志分析记录--获取tableId
     */
    @Override
    public String addHotStandbyLogTable(TableDistCPDTO distCPDTO, String logId) {
        String tbHdfsNum = distCPDTO.getTbHdfsNum() + "/" + distCPDTO.getHdfsHeatBackups().size();
        HotStandbyLogTable hotStandbyLogTable = new HotStandbyLogTable();
        hotStandbyLogTable.setSourceId(logId);
        hotStandbyLogTable.setDbTbName(distCPDTO.getDbTableName());
        hotStandbyLogTable.setTableHdfsNumber(tbHdfsNum);  //初始HDFS数量/过滤HDFS数量
        hotStandbyLogTable.setLogPath(distCPDTO.getLogPath());
        hotStandbyLogTable.setTaskState(ScanCommonConstants.ClusterName.DZX.value);
        hotStandbyLogTable.setSourceName(distCPDTO.getSourceDataName());
        hotStandbyLogTable.setHotStandbyStaTime(DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss"));
        hotStandbyLogTable.setHotStandbyTime("0");
        if (distCPDTO.getSyncRange() == null || distCPDTO.getSyncRange() == 0){
            hotStandbyLogTable.setSyncWay("全量");
        }else {
            hotStandbyLogTable.setSyncWay("增量");
        }
        save(hotStandbyLogTable);
        return hotStandbyLogTable.getId();
    }

    /**
     * 表级日志分析记录修改--用时详情修改
     */
    @Override
    public void upHotLog(String tableId,String str) {
        HotStandbyLogTable hotStandbyLogTable = getById(tableId);
        hotStandbyLogTable.setHotStandbyTimeData(hotStandbyLogTable.getHotStandbyTimeData()+str);
        updateById(hotStandbyLogTable);
    }

    /**
     * 表级日志分析记录修改--执行状态修改
     */
    @Override
    public void upState(String tableId,String state) {
        hotStandbyLogTableMapper.upState(tableId,state,ScanCommonConstants.ClusterName.JXZ.value);
    }

    /**
     * 表级日志分析记录修改--用时详情修改,待执行修改为执行中
     */
    @Override
    public void upByIdExec(String tableId,String state,String str) {
        hotStandbyLogTableMapper.upByIdExec(tableId,state,str);
    }

    /**
     * 表级日志分析记录修改--执行状态修改、用时详情修改，以一张表有多个where条件
     */
    @Override
    public void upByIdStateHotLog(String tableId,String state,String str,Long souCountNum,Long tarCountNum) {
        HotStandbyLogTable hotStandbyLogTable = getById(tableId);
        //判断是否进行中状态
        if (!state.equals(ScanCommonConstants.ClusterName.CG.value) &&
                hotStandbyLogTable.getTaskState().equals(ScanCommonConstants.ClusterName.JXZ.value)){
            log.warn("=========对比状态"+state);
            hotStandbyLogTable.setTaskState(state);
        }
        hotStandbyLogTable.setHotStandbyTimeData(hotStandbyLogTable.getHotStandbyTimeData() + str);
        if (hotStandbyLogTable.getSourceCountNumber() != null && hotStandbyLogTable.getTargetCountNumber() != null){
            hotStandbyLogTable.setSourceCountNumber(hotStandbyLogTable.getSourceCountNumber()+souCountNum);
            hotStandbyLogTable.setTargetCountNumber(hotStandbyLogTable.getTargetCountNumber()+tarCountNum);
        }else {
            hotStandbyLogTable.setSourceCountNumber(souCountNum);
            hotStandbyLogTable.setTargetCountNumber(tarCountNum);
        }
        updateById(hotStandbyLogTable);
    }

    /**
     * 最终修改--表级日志分析记录修改--表级热备
     */
    @Override
    public void upStateHotLog(String tableId,String state,String str,Long souCountNum,Long tarCountNum,String errHD) {
        HotStandbyLogTable hotStandbyLogTable = getById(tableId);
        //判断是否进行中状态 ，判断
        if (hotStandbyLogTable.getTaskState().equals(ScanCommonConstants.ClusterName.JXZ.value) ||
                hotStandbyLogTable.getTaskState().equals(ScanCommonConstants.ClusterName.CG.value)){
            log.warn("=========对比状态"+state);
            hotStandbyLogTable.setTaskState(state);
        }
        //判断当前对比任务为成功,且稽核任务中出现忽略SQL
        if(errHD.equals(ScanCommonConstants.ClusterName.YC.value)&&hotStandbyLogTable.getTaskState().equals(ScanCommonConstants.ClusterName.CG.value)){
            log.warn("=========出现忽略状态"+state);
            hotStandbyLogTable.setTaskState(ScanCommonConstants.ClusterName.BDSB.value);
        }
        String str1 = hotStandbyLogTable.getHotStandbyTimeData() + str;
        Map<String, Object> map = getTimeStr(str1);
        //多个where条件情况
        String logData = (String) map.get("logData");
        long countTime = (long) map.get("countTime");
        hotStandbyLogTable.setHotStandbyTime(DateUtil.formatBetween(DateUtil.offsetSecond(DateUtil.date(),(int)-countTime),DateUtil.date(), BetweenFormater.Level.SECOND));
        hotStandbyLogTable.setHotStandbyTimeData("----------------------模块耗时---------------------"+ "\n"+logData
                +"-----------------开始时间--结束时间-----------------"+ "\n" +str1);
        hotStandbyLogTable.setHotStandbyEndTime(DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss"));
        if (hotStandbyLogTable.getSourceCountNumber() != null && hotStandbyLogTable.getTargetCountNumber() != null){
            hotStandbyLogTable.setSourceCountNumber(hotStandbyLogTable.getSourceCountNumber()+souCountNum);
            hotStandbyLogTable.setTargetCountNumber(hotStandbyLogTable.getTargetCountNumber()+tarCountNum);
        }else {
            hotStandbyLogTable.setSourceCountNumber(souCountNum);
            hotStandbyLogTable.setTargetCountNumber(tarCountNum);
        }
        updateById(hotStandbyLogTable);
    }

    /**
     * 获取每个模块执行时间,和总用时
     * @param hotStandbyTimeData
     * @return
     */
    private Map<String,Object> getTimeStr(String hotStandbyTimeData) {
        String str = "";
        long count = 0L;
        Map<String,Object> map = new HashMap<>();
        String[] split = hotStandbyTimeData.split("\n");
        for (String s : split) {
            if (s.length()>6){
                String[] split1 = s.substring(6).split("--");
                if (split1.length == 2){
                    long betweenDay = DateUtil.between(DateUtil.parse(split1[0]), DateUtil.parse(split1[1]), DateUnit.SECOND);
                    count += betweenDay;
                    str += s.substring(0,6)+DateUtil.formatBetween(DateUtil.parse(split1[0]), DateUtil.parse(split1[1]), BetweenFormater.Level.SECOND) +"\n";
                }
            }
        }
        map.put("logData",str);
        map.put("countTime",count);
        return map;
    }
}
